home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Other Langs / MacPerl ƒ / Perl Source ƒ / MacPerl / MPPreferences.c < prev    next >
Text File  |  1993-12-11  |  17KB  |  794 lines

  1. /*********************************************************************
  2. Project    :    MacPerl                -    Real Perl Application
  3. File        :    MPPreferences.c    -    Handle Preference Settings
  4. Author    :    Matthias Neeracher
  5.  
  6. A lot of this code is borrowed from 7Edit written by
  7. Apple Developer Support UK
  8.  
  9. Started    :    08Dec93                                Language    :    MPW C
  10. Modified    :    08Dec93    MN    Separated from MPUtils
  11. Last        :    08Dec93
  12. *********************************************************************/
  13.  
  14. #include <PLStringFuncs.h>
  15. #include <Events.h>
  16. #include <Traps.h>
  17. #include <Dialogs.h>
  18. #include <Fonts.h>
  19. #include <Packages.h>
  20. #include <ToolUtils.h>
  21. #include <AppleEvents.h>
  22. #include <TFileSpec.h>
  23. #include <Folders.h>
  24. #include <Resources.h>
  25. #include <OSUtils.h>
  26. #include <Files.h>
  27. #include <Lists.h>
  28. #include <Icons.h>
  29. #include <string.h>
  30. #include <GUSI.h>
  31. #include <Desk.h>
  32. #include <ctype.h>
  33. #include <stdio.h>
  34.  
  35. #include "MPPreferences.h"
  36. #include "MPUtils.h"
  37. #include "MPWindow.h"
  38. #include <patchlevel.h>
  39.  
  40. pascal void OpenPreferenceFile(FSSpec * spec)
  41. {
  42.     Str255        name;
  43.     short            oldResFile;
  44.     short            res;
  45.     short    **        defaultfont;
  46.     PerlPrefs **prefs;
  47.     
  48.     oldResFile    =    CurResFile();
  49.  
  50.     gPrefsFile = HOpenResFile(spec->vRefNum, spec->parID, spec->name, fsRdWrPerm);
  51.     
  52.     if (gPrefsFile == -1) {
  53.         gPrefsFile = 0;
  54.          
  55.         return;
  56.     }
  57.     
  58.     if (!Get1Resource('STR#', LibraryPaths)) {
  59.         Handle    lib;
  60.         short        count = 1;
  61.         char        len;
  62.         char *    libpath;
  63.         FSSpec    libspec;
  64.         
  65.         libspec.vRefNum    =     gAppVol;
  66.         libspec.parID    =    gAppDir;
  67.         PLstrcpy(libspec.name, "\plib");
  68.         
  69.         libpath  = FSp2FullPath(&libspec);
  70.         len        = strlen(libpath);
  71.         
  72.         PtrToHand((Ptr) &count, &lib, sizeof(short));
  73.         PtrAndHand((Ptr) &len, lib, 1);
  74.         PtrAndHand(libpath, lib, len);
  75.         
  76.         AddResource(lib, 'STR#', LibraryPaths, "\p");
  77.     }
  78.     
  79.     if (!(defaultfont = (short **) Get1Resource('PFNT', 128))) {
  80.         Handle    font;
  81.         
  82.         PtrToHand((Ptr) &gFormat.size, &font, sizeof(short));
  83.         GetFontName(gFormat.font, name);
  84.         AddResource(font, 'PFNT', 128, name);
  85.     } else {
  86.         OSType type;
  87.         
  88.         GetResInfo((Handle) defaultfont, &res, &type, name);
  89.         GetFNum(name, &gFormat.font);
  90.         
  91.         if (gFormat.font)
  92.             gFormat.size = **defaultfont;
  93.         else {
  94.             gFormat.font = GetAppFont();
  95.             gFormat.size = GetDefFontSize();
  96.         }
  97.     }
  98.  
  99.     if (!(prefs = (PerlPrefs **) Get1Resource('PPRF', 128))) {
  100.         PtrToHand((Ptr) &gPerlPrefs, (Handle *)&prefs, sizeof(PerlPrefs));
  101.         AddResource((Handle) prefs, 'PPRF', 128, "\p");
  102.     } else
  103.         gPerlPrefs = **prefs;
  104.     
  105.     UseResFile(oldResFile);
  106. }
  107.  
  108. pascal void OpenPreferences()
  109. {
  110.     FSSpec        prefPath;
  111.     CInfoPBRec    info;
  112.     FCBPBRec        fcb;
  113.     Str63            name;
  114.  
  115.     gPrefsFile = 0;
  116.     
  117.     GetFNum("\pMonaco", &gFormat.font);
  118.     gFormat.size = gFormat.font ? 9 : GetDefFontSize();
  119.     gFormat.font = gFormat.font ? gFormat.font : GetAppFont();
  120.     
  121.     fcb.ioNamePtr    =    &name;
  122.     fcb.ioRefNum    =    CurResFile();
  123.     fcb.ioFCBIndx    =    0;
  124.     
  125.     PBGetFCBInfoSync(&fcb);
  126.     
  127.     gAppVol    =    fcb.ioFCBVRefNum;
  128.     gAppDir    =    fcb.ioFCBParID;
  129.     
  130.     prefPath.vRefNum     = gAppVol;
  131.     prefPath.parID        = gAppDir;
  132.     PLstrcpy(prefPath.name, "\pMacPerl Preferences");
  133.     
  134.     if (FSpCatInfo(&prefPath, &info))
  135.         if (FindFolder(
  136.             kOnSystemDisk, 
  137.             kPreferencesFolderType, 
  138.             true, 
  139.             &prefPath.vRefNum,
  140.             &prefPath.parID)
  141.         )
  142.             return;
  143.             
  144.     if (FSpCatInfo(&prefPath, &info)) {
  145.         if (HCreate(prefPath.vRefNum, prefPath.parID, prefPath.name, 'McPL', 'pref'))
  146.             return;
  147.             
  148.         HCreateResFile(prefPath.vRefNum, prefPath.parID, prefPath.name);
  149.     }
  150.     
  151.     OpenPreferenceFile(&prefPath);
  152. }
  153.  
  154. static short        PrefSubDialog     =     1;
  155. static short        PathCount;
  156. static ListHandle    PathList;
  157.  
  158. pascal void DrawPrefIcon(DialogPtr dlg, short item)
  159. {
  160.     short        kind;
  161.     Handle    h;
  162.     Rect        r;
  163.     Str31        title;
  164.     FontInfo    info;
  165.         
  166.     GetDItem(dlg, item, &kind, &h, &r);
  167. #ifndef RUNTIME
  168.     PlotIconID(&r, atNone, (item == PrefSubDialog) ? ttSelected : ttNone, PrefDialog+item);
  169. #else
  170.     PlotResICN_(PrefDialog+item, &r, (item == PrefSubDialog) ? iconHilited : iconPlain);
  171. #endif
  172.     GetIndString(title, PrefDialog, item);
  173.  
  174.     TextFont(1);
  175.     TextSize(9);
  176.     GetFontInfo(&info);
  177.  
  178.     MoveTo(r.left - (StringWidth(title) - 32 >> 1), r.bottom+2+info.ascent);
  179.     DrawString(title);
  180.     
  181.     if (item == PrefSubDialog) {
  182.         
  183.         r.top     = r.bottom + 2;
  184.         r.bottom = r.top + info.ascent+info.descent+info.leading+2;
  185.         r.left     = r.left - (StringWidth(title) - 32 >> 1) - 1;
  186.         r.right  = r.left + StringWidth(title) + 2;
  187.         
  188.         InvertRect(&r);
  189.     }
  190.     
  191.     TextFont(0);
  192.     TextSize(12);
  193. }
  194.  
  195. pascal void DrawPathList(DialogPtr dlg, short item)
  196. {
  197. #pragma unused(item)
  198.     Rect    r;
  199.     
  200.     TextFont(0);
  201.     TextSize(12);
  202.     LUpdate(dlg->visRgn, PathList);
  203.     r = (*PathList)->rView;
  204.     InsetRect(&r, -1, -1);
  205.     FrameRect(&r);
  206. }
  207.  
  208. pascal Boolean PrefLibFilter(DialogPtr dlg, EventRecord * ev, short * item)
  209. {
  210.     Point         cell;
  211.     short            kind;
  212.     short            len;
  213.     int            length;
  214.     Handle        h;
  215.     Rect            r;
  216.     WindowPtr    win;
  217.     char            msg[50];
  218.     char            contents[256];
  219.     
  220.     SetPort(dlg);
  221.     switch (ev->what) {
  222.     case keyDown:
  223.         switch (ev->message & charCodeMask) {
  224.         case '\n':
  225.         case 3:
  226.             *item = pd_Done;
  227.             
  228.             return true;
  229.         case 8:
  230.             *item = pld_Remove;
  231.             
  232.             return true;
  233.         default:
  234.             break;
  235.         }
  236.     case mouseDown:
  237.         switch (FindWindow(ev->where, &win)) {
  238.         case inDrag:
  239.             if (win != dlg)
  240.                 return false;
  241.                 
  242.             r = qd.screenBits.bounds;
  243.             InsetRect(&r, 10, 10);
  244.             DragWindow(win, ev->where, &r);
  245.             
  246.             ev->what = nullEvent;
  247.             
  248.             return false;
  249.         case inSysWindow:
  250.             SystemClick(ev, win);
  251.             
  252.             ev->what = nullEvent;
  253.             
  254.             return false;
  255.         case inContent:
  256.             break;
  257.         default:
  258.             return false;
  259.         }
  260.         TextFont(0);
  261.         TextSize(12);
  262.         cell = ev->where;
  263.         GlobalToLocal(&cell);
  264.         GetDItem(dlg, pld_List, &kind, &h, &r);
  265.         if (PtInRect(cell, &r)) {
  266.             if (LClick(cell, ev->modifiers, PathList))
  267.                 for (SetPt(&cell, 0, 0); LGetSelect(true, &cell, PathList); ++cell.v) {
  268.                     len = 256;
  269.                     LGetCell(contents, &len, cell, PathList);
  270.                     contents[len] = 0;
  271.                     length = 256;
  272.                     getindstring(msg, PrefDialog, pd_ChangePath);
  273.                     if (!choose(AF_FILE, 0, msg, nil, CHOOSE_DEFAULT|CHOOSE_DIR, contents, &length))
  274.                         LSetCell((Ptr) contents, length, cell, PathList);
  275.                 } 
  276.             ev->what = nullEvent;
  277.         }
  278.         break;            
  279.     case activateEvt:
  280.         LActivate(ev->modifiers & activeFlag, PathList);
  281.         break;
  282.     case updateEvt:
  283.         if ((WindowPtr) ev->message != dlg) {
  284.             DoUpdate(DPtrFromWindowPtr((WindowPtr)ev->message));
  285.             
  286.             ev->what = nullEvent;
  287.         }
  288.         break;
  289.     }
  290.     
  291.     return false;
  292. }
  293.  
  294. static short PrefsLibDialog(DialogPtr prefs, short resFile)
  295. {
  296.     short            item;
  297.     short            kind;
  298.     short            len;
  299.     int            length;
  300.     Boolean        done;
  301.     Handle        h;
  302.     Handle        paths;
  303.     Point            cell;
  304.     Rect            bounds;
  305.     Rect            dbounds;
  306.     char            msg[50];
  307.     Str255        contents;
  308.  
  309.     UseResFile(gPrefsFile);
  310.     
  311.     paths         = Get1Resource('STR#', LibraryPaths);
  312.     PathCount    = **(short **)paths;
  313.  
  314.     UseResFile(resFile);
  315.     
  316. #ifndef RUNTIME
  317.     h    = GetResource('DITL', PrefDialog+PrefSubDialog);
  318.     AppendDITL(prefs, h, overlayDITL); 
  319. #else
  320.     Append_DITL(prefs, PrefDialog+PrefSubDialog);
  321. #endif
  322.  
  323.     GetDItem(prefs, pld_List, &kind, &h, &bounds);
  324.     SetDItem(prefs, pld_List, kind, (Handle) DrawPathList, &bounds);
  325.         
  326.     SetPt(&cell, bounds.right - bounds.left, 16);
  327.     SetRect(&dbounds, 0, 0, 1, PathCount);
  328.     PathList = LNew(&bounds, &dbounds, cell, 0, prefs, false, false, false, true);
  329.     
  330.     UseResFile(gPrefsFile);
  331.     SetPt(&cell, 0, 0);
  332.     for (; cell.v < PathCount; ++cell.v) {
  333.         GetIndString(contents, LibraryPaths, cell.v + 1);
  334.         LSetCell((Ptr)contents+1, contents[0], cell, PathList);
  335.     }
  336.     UseResFile(resFile);
  337.     
  338.     LDoDraw(true, PathList);
  339.     ShowWindow(prefs);
  340.         
  341.     for (done = false; !done; ) {
  342.         ModalDialog(PrefLibFilter, &item);
  343.         switch (item) {
  344.         case pd_Done:
  345.         case pd_ScriptIcon:
  346.             done = true;
  347.             break;
  348.         case pld_Remove:
  349.             SetPt(&cell, 0, 0);
  350.             
  351.             if (LGetSelect(true, &cell, PathList) && Alert(PrefLibDelID, nil) == 1)
  352.                 do {
  353.                     LDelRow(1, cell.v, PathList);
  354.                         
  355.                     --PathCount;
  356.                 } while (LGetSelect(true, &cell, PathList));
  357.                 
  358.             break;
  359.         case pld_Add:
  360.             length = 256;
  361.             getindstring(msg, PrefDialog, pd_AddPath);
  362.             if (!choose(AF_FILE, 0, msg, nil, CHOOSE_DIR, contents, &length)) {
  363.                     SetPt(&cell, 0, PathCount);
  364.                     LAddRow(1, PathCount++, PathList);
  365.                     LSetCell(contents, length, cell, PathList);
  366.             }    
  367.             break;
  368.         }
  369.     }
  370.     
  371.     PtrToXHand(&PathCount, paths, sizeof(short));
  372.     SetPt(&cell, 0, 0);
  373.     for (; cell.v < PathCount; ++cell.v) {
  374.         len = 255;
  375.         LGetCell((Ptr) contents+1, &len, cell, PathList);
  376.         contents[0] = len;
  377.         
  378.         PtrAndHand(contents, paths, len+1);
  379.     }
  380.     
  381.     ChangedResource((Handle) paths);
  382.     WriteResource((Handle) paths);
  383.     
  384.     LDispose(PathList);
  385.  
  386. #ifndef RUNTIME
  387.     ShortenDITL(prefs, CountDITL(prefs) - pd_Outline);
  388. #else
  389.     Shorten_DITL(prefs, Count_DITL(prefs) - pd_Outline);
  390. #endif
  391.  
  392.     return item;
  393. }
  394.  
  395. pascal Boolean PrefScriptFilter(DialogPtr dlg, EventRecord * ev, short * item)
  396. {    
  397.     WindowPtr    win;
  398.     Rect            r;
  399.     
  400.     SetPort(dlg);
  401.     switch (ev->what) {
  402.     case keyDown:
  403.         switch (ev->message & charCodeMask) {
  404.         case '\n':
  405.         case 3:
  406.             *item = pd_Done;
  407.             
  408.             return true;
  409.         default:
  410.             break;
  411.         }
  412.     case mouseDown:
  413.         switch (FindWindow(ev->where, &win)) {
  414.         case inDrag:
  415.             if (win != dlg)
  416.                 return false;
  417.                 
  418.             r = qd.screenBits.bounds;
  419.             InsetRect(&r, 10, 10);
  420.             DragWindow(win, ev->where, &r);
  421.             
  422.             ev->what = nullEvent;
  423.             
  424.             return false;
  425.         case inSysWindow:
  426.             SystemClick(ev, win);
  427.             
  428.             ev->what = nullEvent;
  429.             
  430.             return false;
  431.         default:
  432.             return false;
  433.         }
  434.     case updateEvt:
  435.         if ((WindowPtr) ev->message != dlg) {
  436.             DoUpdate(DPtrFromWindowPtr((WindowPtr)ev->message));
  437.             
  438.             ev->what = nullEvent;
  439.         }
  440.         break;
  441.     }
  442.     
  443.     return false;
  444. }
  445.  
  446. static short PrefsScriptDialog(DialogPtr prefs, short resFile)
  447. {
  448.     short            item;
  449.     short            kind;
  450.     Boolean        done;
  451.     Handle        h;
  452.     Handle        pref;
  453.     Rect            bounds;
  454.     
  455. #ifndef RUNTIME
  456.     h    = GetResource('DITL', PrefDialog+PrefSubDialog);
  457.     AppendDITL(prefs, h, overlayDITL); 
  458. #else
  459.     Append_DITL(prefs, PrefDialog+PrefSubDialog);
  460. #endif
  461.     
  462.     GetDItem(prefs, psd_Edit, &kind, &h, &bounds);
  463.     SetControlValue((ControlHandle) h, !gPerlPrefs.runFinderOpens);
  464.     GetDItem(prefs, psd_Run, &kind, &h, &bounds);
  465.     SetControlValue((ControlHandle) h, gPerlPrefs.runFinderOpens);
  466.     GetDItem(prefs, psd_Check, &kind, &h, &bounds);
  467.     SetControlValue((ControlHandle) h, gPerlPrefs.checkType);
  468.             
  469.     for (done = false; !done; ) {
  470.         ModalDialog(PrefScriptFilter, &item);
  471.         switch (item) {
  472.         case pd_Done:
  473.         case pd_LibIcon:
  474.             done = true;
  475.             break;
  476.         case psd_Edit:
  477.         case psd_Run:
  478.             gPerlPrefs.runFinderOpens = item == psd_Run;
  479.             GetDItem(prefs, psd_Edit, &kind, &h, &bounds);
  480.             SetControlValue((ControlHandle) h, !gPerlPrefs.runFinderOpens);
  481.             GetDItem(prefs, psd_Run, &kind, &h, &bounds);
  482.             SetControlValue((ControlHandle) h, gPerlPrefs.runFinderOpens);
  483.             break;
  484.         case psd_Check:
  485.             gPerlPrefs.checkType = !gPerlPrefs.checkType;
  486.             GetDItem(prefs, psd_Check, &kind, &h, &bounds);
  487.             SetControlValue((ControlHandle) h, gPerlPrefs.checkType);
  488.             break;
  489.         }
  490.     }
  491.  
  492.     UseResFile(gPrefsFile);
  493.     if (pref = Get1Resource('PPRF', 128)) {
  494.         PtrToXHand((Ptr) &gPerlPrefs, pref, sizeof(PerlPrefs));
  495.         ChangedResource((Handle) pref);
  496.         WriteResource((Handle) pref);
  497.     }
  498.     UseResFile(resFile);
  499.  
  500. #ifndef RUNTIME
  501.     ShortenDITL(prefs, CountDITL(prefs) - pd_Outline);
  502. #else
  503.     Shorten_DITL(prefs, Count_DITL(prefs) - pd_Outline);
  504. #endif
  505.  
  506.     return item;
  507. }
  508.  
  509. pascal void DoPrefDialog()
  510. {
  511.     short            resFile;
  512.     short            kind;
  513.     Handle        h;
  514.     DialogPtr    prefs;
  515.     Rect            bounds;
  516.     
  517.     resFile        = CurResFile();
  518.  
  519.     prefs = GetNewDialog(PrefDialog, nil, (WindowPtr) -1);
  520.  
  521.     GetDItem(prefs, pd_LibIcon, &kind, &h, &bounds);
  522.     SetDItem(prefs, pd_LibIcon, kind, (Handle) DrawPrefIcon, &bounds);
  523.  
  524.     GetDItem(prefs, pd_ScriptIcon, &kind, &h, &bounds);
  525.     SetDItem(prefs, pd_ScriptIcon, kind, (Handle) DrawPrefIcon, &bounds);
  526.  
  527.     GetDItem(prefs, pd_Boundary, &kind, &h, &bounds);
  528.     SetDItem(prefs, pd_Boundary, kind, (Handle) Separator, &bounds);
  529.  
  530.     AdornDefaultButton(prefs, pd_Outline);
  531.  
  532.     ShowWindow(prefs);
  533.  
  534.     PrefSubDialog = pd_LibIcon;
  535.     PrefSubDialog = PrefsLibDialog(prefs, resFile);
  536.     
  537.     while (PrefSubDialog != pd_Done) {
  538.         SetPort(prefs);
  539.         InvalRect(&prefs->portRect);
  540.         EraseRect(&prefs->portRect);
  541.         switch (PrefSubDialog) {
  542.         case pd_LibIcon:
  543.             PrefSubDialog = PrefsLibDialog(prefs, resFile);
  544.             break;
  545.         case pd_ScriptIcon:
  546.             PrefSubDialog = PrefsScriptDialog(prefs, resFile);
  547.             break;
  548.         }
  549.     }
  550.         
  551.     UpdateResFile(gPrefsFile);
  552.  
  553.     DisposeDialog(prefs);
  554. }
  555.  
  556. static ListHandle FontList;
  557. static ListHandle    SizeList;
  558.  
  559. pascal void DrawFontList(DialogPtr dlg, short item)
  560. {
  561. #pragma unused(item)
  562.     Rect    r;
  563.     
  564.     TextFont(0);
  565.     TextSize(12);
  566.     LUpdate(dlg->visRgn, FontList);
  567.     r = (*FontList)->rView;
  568.     InsetRect(&r, -1, -1);
  569.     FrameRect(&r);
  570. }
  571.  
  572. pascal void DrawSizeList(DialogPtr dlg, short item)
  573. {
  574. #pragma unused(item)
  575.     Rect    r;
  576.     
  577.     TextFont(0);
  578.     TextSize(12);
  579.     LUpdate(dlg->visRgn, SizeList);
  580.     r = (*SizeList)->rView;
  581.     InsetRect(&r, -1, -1);
  582.     FrameRect(&r);
  583. }
  584.  
  585. static short SizeChoice[] = 
  586. {
  587.     9,
  588.     10,
  589.     12,
  590.     14,
  591.     18,
  592.     24
  593. };
  594.  
  595. const short    SizeChoiceCount = 6;
  596.  
  597. pascal Boolean FormatFilter(DialogPtr dlg, EventRecord * ev, short * item)
  598. {    
  599.     WindowPtr    win;
  600.     Rect            r;
  601.     
  602.     SetPort(dlg);
  603.     switch (ev->what) {
  604.     case keyDown:
  605.         switch (ev->message & charCodeMask) {
  606.         case '\n':
  607.         case 3:
  608.             *item = fd_OK;
  609.             
  610.             return true;
  611.         case '.':
  612.             if (!(ev->modifiers & cmdKey))
  613.                 break;
  614.         case 27:
  615.             *item = fd_Cancel;
  616.             
  617.             return true;
  618.         default:
  619.             break;
  620.         }
  621.     case mouseDown:
  622.         switch (FindWindow(ev->where, &win)) {
  623.         case inDrag:
  624.             if (win != dlg)
  625.                 return false;
  626.                 
  627.             r = qd.screenBits.bounds;
  628.             InsetRect(&r, 10, 10);
  629.             DragWindow(win, ev->where, &r);
  630.             
  631.             ev->what = nullEvent;
  632.             break;
  633.         case inSysWindow:
  634.             SystemClick(ev, win);
  635.             
  636.             ev->what = nullEvent;
  637.             break;
  638.         }
  639.         return false;
  640.     case activateEvt:
  641.         LActivate(ev->modifiers & activeFlag, FontList);
  642.         LActivate(ev->modifiers & activeFlag, SizeList);
  643.         break;
  644.     case updateEvt:
  645.         if ((WindowPtr) ev->message != dlg) {
  646.             DoUpdate(DPtrFromWindowPtr((WindowPtr)ev->message));
  647.             
  648.             ev->what = nullEvent;
  649.         }
  650.         break;
  651.     }
  652.     
  653.     return false;
  654. }
  655.  
  656. pascal Boolean DoFormatDialog(DocFormat * form, Boolean * defaultFormat)
  657. {
  658.     short            item;
  659.     short            kind;
  660.     short         digit;
  661.     Boolean        done;
  662.     Handle        h;
  663.     DialogPtr    format;
  664.     Point            cell;
  665.     Rect            bounds;
  666.     Rect            dbounds;
  667.     Str255        contents;
  668.     MenuHandle    fonts;
  669.     
  670.     format = GetNewDialog(FormatDialog, nil, (WindowPtr) -1);
  671.  
  672.     GetDItem(format, fd_Separator, &kind, &h, &bounds);
  673.     SetDItem(format, fd_Separator, kind, (Handle) Separator, &bounds);
  674.  
  675.     GetDItem(format, fd_FontList, &kind, &h, &bounds);
  676.     SetDItem(format, fd_FontList, kind, (Handle) DrawFontList, &bounds);
  677.         
  678.     fonts = NewMenu(FormatDialog, "\pFonts");
  679.     AppendResMenu(fonts, 'FONT');
  680.  
  681.     bounds.right -= 16;
  682.     SetPt(&cell, bounds.right - bounds.left, 16);
  683.     SetRect(&dbounds, 0, 0, 1, CountMItems(fonts));
  684.     FontList = LNew(&bounds, &dbounds, cell, 0, format, false, false, false, true);
  685.     
  686.     SetPt(&cell, 0, 0);
  687.     for (; cell.v < CountMItems(fonts); ++cell.v) {
  688.         GetItem(fonts, cell.v+1, contents);
  689.         LSetCell((Ptr)contents+1, contents[0], cell, FontList);
  690.         GetFNum(contents, &kind);
  691.         LSetSelect(form->font == kind, cell, FontList);
  692.     }
  693.  
  694.     GetDItem(format, fd_SizeList, &kind, &h, &bounds);
  695.     SetDItem(format, fd_SizeList, kind, (Handle) DrawSizeList, &bounds);
  696.  
  697.     bounds.right -= 16;
  698.     SetPt(&cell, bounds.right - bounds.left, 16);
  699.     SetRect(&dbounds, 0, 0, 1, SizeChoiceCount);
  700.     SizeList = LNew(&bounds, &dbounds, cell, 0, format, false, false, false, true);
  701.     
  702.     SetPt(&cell, 0, 0);
  703.     for (; cell.v < SizeChoiceCount; ++cell.v) {
  704.         sprintf((char *) contents, "%d", SizeChoice[cell.v]);
  705.         LSetCell((Ptr)contents, strlen((Ptr) contents), cell, SizeList);
  706.         LSetSelect(form->size == SizeChoice[cell.v], cell, SizeList);
  707.     }
  708.     
  709.     AdornDefaultButton(format, fd_Outline);
  710.  
  711.     LDoDraw(true, FontList);
  712.     LDoDraw(true, SizeList);
  713.     
  714.     sprintf((char *) contents+1, "%d", form->size);
  715.     contents[0] = strlen((Ptr) contents+1);
  716.     SetText(format, fd_SizeEdit, contents);
  717.     SelIText(format, fd_SizeEdit, 0, 32767);
  718.  
  719.     if (*defaultFormat) {
  720.         GetDItem(format, fd_MakeDefault, &kind, &h, &bounds);
  721.         SetControlValue((ControlHandle) h, 1);
  722.         HiliteControl((ControlHandle) h, 254);
  723.     }
  724.     
  725.     ShowWindow(format);
  726.         
  727.     for (done = false; !done; ) {
  728.         ModalDialog(FormatFilter, &item);
  729.         
  730.         switch (item) {
  731.         case fd_OK:
  732.             RetrieveText(format, fd_SizeEdit, contents);
  733.             if (contents[0]) {
  734.                 for (digit = 0, kind = 0; digit++ < contents[0]; )
  735.                     if (isdigit(contents[digit]))
  736.                         kind = kind * 10 + contents[digit] - '0';
  737.                     else {
  738.                         kind = 0;
  739.                         
  740.                         break;
  741.                     }
  742.                 
  743.                 if (kind) {
  744.                     form->size = kind;
  745.                     SetPt(&cell, 0, 0);
  746.                     LGetSelect(true, &cell, FontList);
  747.                     GetItem(fonts, cell.v+1, contents);
  748.                     GetFNum(contents, &kind);
  749.                     form->font = kind;
  750.                     
  751.                     done = true;
  752.                     break;
  753.                 }
  754.             }
  755.             
  756.             SelIText(format, fd_SizeEdit, 0, 32767);
  757.             SysBeep(0);
  758.             
  759.             item = 0;
  760.             break;
  761.         case fd_Cancel:
  762.             done = true;
  763.             *defaultFormat = false;
  764.             break;
  765.         case fd_FontList:
  766.             GetMouse(&cell);
  767.             LClick(cell, 0, FontList);
  768.             break;
  769.         case fd_SizeList:
  770.             GetMouse(&cell);
  771.             LClick(cell, 0, SizeList);
  772.             SetPt(&cell, 0, 0);
  773.             if (LGetSelect(true, &cell, SizeList)) {
  774.                 sprintf((char *) contents+1, "%d", SizeChoice[cell.v]);
  775.                 contents[0] = strlen((Ptr) contents+1);
  776.                 SetText(format, fd_SizeEdit, contents);
  777.                 SelIText(format, fd_SizeEdit, 0, 32767);
  778.             }
  779.             break;
  780.         case fd_MakeDefault:
  781.             GetDItem(format, fd_MakeDefault, &kind, &h, &bounds);
  782.             SetControlValue((ControlHandle) h, *defaultFormat = !*defaultFormat);
  783.             break;
  784.         }
  785.     }
  786.     
  787.     LDispose(FontList);
  788.     LDispose(SizeList);
  789.     DisposeDialog(format);
  790.     DisposeMenu(fonts);
  791.     
  792.     return (item == fd_OK);
  793. }
  794.